package com.feicheng.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feicheng.common.constant.Constant;
import com.feicheng.common.exception.SystemException;
import com.feicheng.common.message.LoginMessage;
import com.feicheng.common.result.ResultInfo;
import com.feicheng.common.util.StringGenerator;
import com.feicheng.persistence.entity.*;
import com.feicheng.persistence.model.PermissionModel;
import com.feicheng.persistence.service.*;
import com.feicheng.service.IFLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import jakarta.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

/**
 * 管理平台端使用用户名和密码验证登录
 * @see IFLoginService
 */
@Service
public class FAdminPasswordLoginServiceImpl implements IFLoginService {

    @Autowired
    IUserService iUserService;

    @Autowired
    IRoleService iRoleService;

    @Autowired
    IPermissionService iPermissionService;

    @Autowired
    IEmpService iEmpService;

    @Autowired
    IEmpDeptService iEmpDeptService;

    @Autowired
    IDeptService iDeptService;

    @Autowired
    IJobService iJobService;

    @Autowired
    HttpSession session;

    @Autowired
    LoginMessage loginMessage;

    /**
     * 登录逻辑
     * @see IFLoginService#login(String) 刘灌宣
     * @param loginParams 登录参数 包含 用户名 密码
     * @return
     */
    @Override
    public ResultInfo login(String loginParams) {

        /* 取得登录所需的参数 账户 和  密码 ，转换出现问题时抛出异常，登录逻辑停止。*/
        JSONObject param = null;
        try {
            param = JSONObject.parseObject(loginParams);
        } catch (JSONException exception) {
            throw new SystemException(loginMessage.getE01());
        }

        // 取得登录所需的参数 账户
        String account = param.getString(Constant.ENTITY.USER.ACCOUNT);

        /* 账户取得失败时抛出异常，登录逻辑停止。 */
        if (!StringUtils.hasLength(account)) {
            throw new SystemException(loginMessage.getE02());
        }

        /* 密码取得失败时抛出异常，登录逻辑停止。 */
        String password = param.getString(Constant.ENTITY.USER.PASSWORD);
        if (!StringUtils.hasLength(password)) {
            throw new SystemException(loginMessage.getE03());
        }

        /* 构建查询条件，以账户为条件。 */
        QueryWrapper<User> qw = new QueryWrapper<User>();
        qw.eq(Constant.ENTITY.USER.ACCOUNT, account);

        /* 查询用户 */
        List<User> resultList = iUserService.list(qw);

        /* 找不到记录时，账户不存在。逻辑停止 */
        if (null == resultList || resultList.size() == 0) {
            throw new SystemException(loginMessage.getE04());
        /* 找到多条记录时，账户非法。逻辑停止 */
        } else if (resultList.size() > 1) {
            throw new SystemException(loginMessage.getE05());
        }

        /* 找且只找到一条时，登录逻辑继续。 */
        User currentUser = resultList.get(0);

        String ecodePassword = StringGenerator.eCodePassword(password,currentUser.getSalt());

        if (!ecodePassword.equals(currentUser.getPassword())) {
            throw new SystemException(loginMessage.getE06());
        }

        /* 构建返回结果，要包含用户信息，角色信息，权限信息。 */
        JSONObject currentUserInfo = new JSONObject();
        currentUserInfo.put("user", currentUser);


        QueryWrapper<Emp> empQueryWrapper = new QueryWrapper<>();
        empQueryWrapper.eq("user_id", currentUser.getUserId());

        List<Emp> empList = iEmpService.list(empQueryWrapper);

        if (null == empList || 0 == empList.size() || 1 < empList.size()) {
            throw new SystemException("数据异常");
        }
        Emp emp = empList.remove(0);
        // 将员工信息保存到返回结果中
        currentUserInfo.put("emp", emp);

        QueryWrapper<EmpDept> empDeptQueryWrapper = new QueryWrapper<>();
        empDeptQueryWrapper.eq("emp_id", emp.getEmpId());
        empDeptQueryWrapper.eq("a_flg", true);
        empDeptQueryWrapper.isNull("et");

        List<EmpDept> empDepts = iEmpDeptService.list(empDeptQueryWrapper);
        if (null == empDepts || 0 == empDepts.size() || 1 < empDepts.size()) {
            throw new SystemException("组织数据异常，登录失败。");
        }
        EmpDept empDept = empDepts.remove(0);

        Dept dept = iDeptService.getById(empDept.getDeptId());
        // 将部门信息保存到返回结果中
        currentUserInfo.put("dept", dept);

        Job job = iJobService.getById(empDept.getJobId());
        // 将职位信息保存到返回结果中
        currentUserInfo.put("job", job);

        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        JSONArray roleCodes = JSONArray.parseArray(currentUser.getRoles());
        if (null == roleCodes || 0 == roleCodes.size()) {
            throw new SystemException("角色数据非法，登录失败。");
        }
        roleQueryWrapper.in("role_code", roleCodes);
        List<Role> roles = iRoleService.list(roleQueryWrapper);
        if (null == roles || 0 == roles.size()) {
            throw new SystemException("角色数据非法，登录失败。");
        }

        // 将角色信息保存到返回结果中
        currentUserInfo.put(Constant.RESULT.ROLE.ROLES, roles);

        HashSet<String> permissionCodes = new HashSet<>();

        for (Role role : roles) {
            JSONArray rolePrmissionCodes = JSONArray.parseArray(role.getPermissions());
            for (int index = 0; index < rolePrmissionCodes.size(); index++) {
                permissionCodes.add(rolePrmissionCodes.get(index).toString());
            }
        }

        if (0 == permissionCodes.size()) {
            throw new SystemException("权限数据非法，登录失败。");
        }
        // 将权限信息code保存到返回结果中
        currentUserInfo.put("permissionCodeString", JSONObject.toJSONString(permissionCodes));

        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.eq("m_flg", true);
        permissionQueryWrapper.eq("a_flg", true);
        permissionQueryWrapper.in("code", permissionCodes);
        permissionQueryWrapper.in("type", "M", "P");
        permissionQueryWrapper.orderByAsc("sort");

        List<Permission> permissions = iPermissionService.list(permissionQueryWrapper);
        if (0 == permissions.size()) {
            throw new SystemException("权限数据非法，登录失败。");
        }

        Map<String, PermissionModel> permissionMap = new HashMap<>();

        for (Permission permission : permissions) {
            PermissionModel model = new PermissionModel();
            model.setAFlg(permission.getAFlg());
            model.setCode(permission.getCode());
            model.setIcon(permission.getIcon());
            model.setMFlg(permission.getMFlg());
            model.setName(permission.getName());
            model.setPath(permission.getPath());
            model.setPCode(permission.getPCode());
            model.setSort(permission.getSort());
            model.setType(permission.getType());
            model.setPermissions(new ArrayList<PermissionModel>());
            permissionMap.put(permission.getCode(), model);
        }

        List<PermissionModel> permissionArray = new ArrayList<>();
        for (Permission permission : permissions) {
            if ("0".equals(permission.getPCode())) {
                permissionArray.add(permissionMap.get(permission.getCode()));
                continue;
            }

            PermissionModel pPermission = permissionMap.get(permission.getPCode());
            pPermission.getPermissions().add(permissionMap.get(permission.getCode()));
        }

        // 将权限信息保存到返回结果中
        currentUserInfo.put(Constant.RESULT.PERMISSION.PERMISSIONS, permissionArray);

        // 返回结果保存到session中
        session.setAttribute(Constant.RESULT.CURRENT, currentUserInfo);

        // 返回结果
        return ResultInfo.success(currentUserInfo);
    }
}
